<template>
	<article class="page page-ip-location container">
		<h4 class="text-center">IP位置查询</h4>
		<form class="content">
			<fieldset>
				<legend>IP位置查询</legend>
				<div class="wrapper">
					<div class="form-group row">
						<label class="col-1 col-form-label">待定位IP</label>
						<div class="col-11">
							<input type="text" class="form-control" v-model.trim="ip" placeholder="请输入待定位的IP地址">
						</div>
					</div>
					<div class="form-group row">
						<label for="ak" class="col-1 col-form-label">AppKey</label>
						<div class="col-11">
							<input type="text" class="form-control" v-model.trim="appKey" placeholder="建议使用自己的开发密钥，若留空则默认使用本人的AK">
						</div>
					</div>
					<div class="form-group row">
						<label class="col-1 col-form-label">坐标类型</label>
						<div class="col-11">
							<select class="form-control" v-model="coor">
								<option value="bd09">百度墨卡托坐标</option>
								<option value="bd09ll">百度经纬度坐标（推荐）</option>
								<option value="gcj02">国测局经纬度坐标</option>
							</select>
						</div>
					</div>
					<div class="form-group row">
						<label class="col-1 col-form-label"></label>
						<div class="col-11">
							<x-button type="primary" block @click="submitForm">查 询</x-button>
						</div>
					</div>
					<div class="form-group row">
						<label class="col-1 col-form-label">目标定位</label>
						<div class="col-11">
							<table class="table table-striped">
								<thead>
									<tr>
										<th v-for="(v,i) in tableHeaders" :key="i">{{v.label}}</th>
									</tr>
								</thead>
								<tbody>
									<tr v-for="(item,index) in tableData" :key="index">
										<td v-for="(v,i) in tableHeaders" :key="i">{{item[v.value]}}</td>
									</tr>
								</tbody>
							</table>
						</div>
					</div>
					<div class="form-group row">
						<label class="col-1 col-form-label">地图定位</label>
						<div class="col-11">
							<div :id="`map_${id}`" class="map"></div>
						</div>
					</div>
				</div>

			</fieldset>
		</form>
		<div class="alert alert-secondary" role="alert">
			<div>1、本程序依托互联网开放的API，不同服务商返回的结果可能存在差异；</div>
			<div>2、地图使用的是百度的开放功能，使用时坐标类型须为“百度经纬度坐标”。</div>
		</div>
	</article>
</template>

<script>
// 百度IP定位Web服务API: https://lbsyun.baidu.com/index.php?title=webapi/ip-api

export default {
	name: 'ip-location',
	data () {
		return {
			id: `${Math.random()}`.substring(2),
			ip: '',
			appKey: '',
			// myAppKey: 'A9s51lsfmYKRy8w6I0DUCbdgRYSzmUyk',
			myAppKey: '',
			coor: 'bd09ll',
			tableHeaders: [
				{label: '服务方', value: 'waiter'},
				{label: 'IP地址', value: 'ip'},
				{label: '经度', value: 'lng'},
				{label: '纬度', value: 'lat'},
				{label: '物理地址', value: 'address'},
			],
			baiduScriptNode: null,
			baiduResult: {
				ip: '',
				address: '',
				address_detail: {city: '', province: ''},
				point: {x: '', y: ''}
			},
			pconlineResult: {
				addr: '', city: '', cityCode: '', err: '', ip: '', pro: '',
				proCode: '', region: '', regionCode: '', regionNames: '',
			}
		}
	},
	computed: {
		tableData () {
			let result = []
			result.push({
				waiter: '百 度',
				ip: this.baiduResult.ip,
				address: this.baiduResult.address,
				lng: (this.baiduResult.point || {}).x,
				lat: (this.baiduResult.point || {}).y,
			})
			result.push({
				waiter: '太平洋',
				ip: this.pconlineResult.ip,
				address: this.pconlineResult.addr,
				lng: '',
				lat: '',
			})
			return result
		}
	},
	methods: {
		submitForm () {
			this.baiduIpLocation()
			this.pconlineIpLocation()
		},
		// 太平洋IP定位
		pconlineIpLocation () {
			let ip = this.ip || ''
			let url = `http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=${ip}`
			this.$jstools.ajax.get(url).then((res) => {
				if (res.data) {
					this.pconlineResult = this.$jstools.jsonParse(res.data)
				} else {
					this.pconlineResult = {
						addr: '', city: '', cityCode: '', err: '', ip: '', pro: '',
						proCode: '', region: '', regionCode: '', regionNames: '',
					}
				}
			})
		},
		// 百度IP定位
		baiduIpLocation () {
			let appKey = this.appKey || this.myAppKey
			let ip = this.ip || ''
			let coor = this.coor || 'bd09ll'
			let url = `http://api.map.baidu.com/location/ip?ak=${appKey}&ip=${ip}&coor=${coor}`
			this.$jstools.ajax.get(url).then((res) => {
				let data = res.data || {}
				if (data.status === 0) {
					this.baiduResult = {ip, ...(data.content || {})}
				} else {
					this.baiduResult = {
						ip,
						address: '',
						address_detail: {city: '', province: ''},
						point: {x: '', y: ''}
					}
				}
				this.loadBaiduMapScript()
			})
		},
		// 百度地图
		loadBaiduMapScript () {
			if (this.baiduScriptNode) {
				document.body.removeChild(this.baiduScriptNode)
			}
			let _this = this
			let url = `https://api.map.baidu.com/api?v=1.0&type=webgl&ak=${this.appKey || this.myAppKey}&callback=baiduMapCallback`
			window.baiduMapCallback = function () {
				// 创建地图实例
				let map = new window.BMapGL.Map(`map_${_this.id}`)
				let {x, y} = _this.baiduResult.point || {}
				// 创建点坐标
				let point = new window.BMapGL.Point(x || 116.404, y || 39.915)
				// 创建标注
				let label = null
				let marker = new window.BMapGL.Marker(point)
				if (_this.baiduResult.ip) {
					label = new window.BMapGL.Label(_this.baiduResult.ip, {
						position: point,
						offset: new window.BMapGL.Size(-40, 5)
					})
				}
				// 初始化地图，设置中心点坐标和地图级别
				map.centerAndZoom(point, 15)
				map.addOverlay(marker)
				label && map.addOverlay(label)
			}
			this.baiduScriptNode = this.loadScript(url)
		},
		// 加载脚本
		loadScript (url) {
			let scriptNode = document.createElement('script')
			scriptNode.src = url
			document.body.appendChild(scriptNode)
			return scriptNode
		},
	},
};
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
.page-ip-location {
	display: flex;
	flex-direction: column;
	.content {
		height: 0;
		flex-grow: 1;
		fieldset {
			height: 100%;
			.wrapper {
				height: calc(100% - 2em);
				overflow: hidden auto;
				.map {
					height: 40vw;
					border-radius: 6px;
					background-color: @bgGrey;
					box-shadow: 0 0 .5em @bgGrey;
				}
			}
		}
	}
	.col-form-label {
		text-align: right;
	}
	.alert-secondary {
		margin-top: 1em;
		line-height: 2;
	}
}
</style>
